#ifndef __DATABASEHELPER_HPP__
#define __DATABASEHELPER_HPP__

#include <mysql/mysql.h>
#include <string>
#include <vector>
#include <map>
#include <stdexcept>

namespace cloud
{

enum DB_ERROR {
    CONNECT_ERROR,
    QUERY_ERROR,
    OTHER_ERROR
};

class MySQLConnector {
public:
    // 构造函数（不自动连接）
    MySQLConnector(const std::string& host,
                 const std::string& user,
                 const std::string& password,
                 const std::string& database,
                 unsigned int port = 3306,
                 const std::string& charset = "utf8")
        : _host(host), _user(user), _password(password),
          _database(database), _port(port), _charset(charset)
    {
        _conn = mysql_init(nullptr);
        if (!_conn) {
            throw std::runtime_error("MySQL initialization failed");
        }
        
        // 设置字符集
        if (mysql_set_character_set(_conn, _charset.c_str()) != 0) {
            disconnect();
            throw std::runtime_error("Failed to set charset");
        }
    }

    // 连接数据库
    bool connect() 
    {
        if (!mysql_real_connect(_conn,
                               _host.c_str(),
                               _user.c_str(),
                               _password.c_str(),
                               _database.c_str(),
                               _port,
                               nullptr,
                               CLIENT_MULTI_STATEMENTS)) // CLIENT_MULTI_STATEMENTS标志允许在一次查询中执行多条SQL语句
        {
            storeError();
            return false;
        }
        return true;
    }

    // 执行SQL查询
    bool executeQuery(const std::string& sql) 
    {
        if (mysql_query(_conn, sql.c_str())) {
            storeError();
            return false;
        }
        return true;
    }

    // 获取查询结果（适用于SELECT语句）
    std::vector<std::map<std::string, std::string>> getResults() 
    {   
        // 数组，存储查询结果[{col1:val1, col2:val2}, {col1:val1, col2:val2},...]
        std::vector<std::map<std::string, std::string>> results; 
        MYSQL_RES* result = mysql_store_result(_conn); // 获取完整的结果集
        if (!result) {
            storeError();
            return results;
        }

        my_ulonglong row_count = mysql_num_rows(result); // 多少行
        unsigned int col_count = mysql_num_fields(result); // 多少列
        MYSQL_FIELD* fields = mysql_fetch_fields(result); // 结果集，主要来获取列名
        
        // 获取列名
        std::vector<std::string> column_names;
        for (unsigned int i = 0; i < col_count; ++i) {
            column_names.emplace_back(fields[i].name);
        }
        
        // 遍历结果集
        MYSQL_ROW row;
        for(int i=0; i<row_count; i++) {
            row = mysql_fetch_row(result);
            std::map<std::string, std::string> record;
            unsigned long* lengths = mysql_fetch_lengths(result); // 当前行中所有列的长度
            for (unsigned int j = 0; j < col_count; ++j) {
                std::string value = std::string(row[j], lengths[j]); // 取出当前行的每一列的值
                record[column_names[j]] = value; // 存入map
            }
            results.emplace_back(record);
        }
        // MYSQL_ROW row;
        // while ((row = mysql_fetch_row(result))) {
        //     std::map<std::string, std::string> record;
        //     unsigned long* lengths = mysql_fetch_lengths(result);
        //     for (unsigned int i = 0; i < col_count; ++i) {
        //         std::string value;
        //         if (row[i]) {
        //             value = std::string(row[i], lengths[i]);
        //         }
        //         record[column_names[i]] = value;
        //     }
        //     results.emplace_back(record);
        // }
        mysql_free_result(result);
        return results;
    }

    // 断开连接
    void disconnect() 
    {
        if (_conn) {
            mysql_close(_conn);
            _conn = nullptr;
        }
    }

    // 获取错误信息
    std::string getLastError() const 
    {
        return _lastError;
    }

    // 析构函数
    ~MySQLConnector() 
    {
        disconnect();
    }

     // 开启事务
    bool beginTransaction() {
        return executeQuery("START TRANSACTION");
    }

    // 提交事务
    bool commit() {
        return executeQuery("COMMIT");
    }

    // 回滚事务
    bool rollBack() {
        return executeQuery("ROLLBACK");
    }
private:
    // 存储错误信息
    void storeError() 
    {
        if (_conn) {
            _lastError = mysql_error(_conn);
        } else {
            _lastError = "Connection not initialized";
        }
    }

    MYSQL* _conn = nullptr;
    std::string _host;
    std::string _user;
    std::string _password;
    std::string _database;
    unsigned int _port;
    std::string _charset;
    std::string _lastError;
};

} // namespace cloud

#endif